/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Foundation Framework Class Library
 * Version 2.00
 * 
 * Point Reference Class
 *      Provides a class for storing a set of co-ordinates.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
using System;
using System.Drawing;

namespace Adaptive.Foundation
{
    /// <summary>
    /// Provides a class for storing a set of co-ordinates.
    /// </summary>
    public class PointReference 
    {
        /*--------------------------------------------------------------------------------
         * Private Member Declarations
         *------------------------------------------------------------------------------*/
        #region Private Member Declarations

        private int _x;
        private int _y;

        #endregion

        /*--------------------------------------------------------------------------------
         * Constructor / Dispose / Destructor Methods
         *------------------------------------------------------------------------------*/
        #region Constructor / Dispose / Destructor Methods
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <remarks>
        /// This is the default constructor.
        /// </remarks>
        public PointReference()
        {
        }
        /// <summary>
        /// Initializes a new instance of the class to the specified
        /// co-ordinates.
        /// </summary>
        /// <param name="X">
        /// The X co-ordinate value.
        /// </param>
        /// <param name="Y">
        /// The Y co-ordinate value.
        /// </param>
        public PointReference(int X, int Y)
        {
            _x = X;
            _y = Y;
        }
        /// <summary>
        /// Initializes a new instance of the class to the specified
        /// co-ordinates.
        /// </summary>
        /// <param name="point">
        /// A <see cref="System.Drawing.Point"/> structure containing the 
        /// co-ordinate values.
        /// </param>
        public PointReference(Point point)
        {
            _x = point.X;
            _y = point.Y;
        }
        #endregion

        /*--------------------------------------------------------------------------------
         * Public Properties
         *------------------------------------------------------------------------------*/
        #region Public Properties
        /// <summary>
        /// Gets or sets the X co-ordinate value.
        /// </summary>
        /// <value>
        /// An integer left or X co-ordinate value.
        /// </value>
        public int X
        {
            get { return _x; }
            set { _x = value; }
        }
        /// <summary>
        /// Gets or sets the Y co-ordinate value.
        /// </summary>
        /// <value>
        /// An integer top or Y co-ordinate value.
        /// </value>
        public int Y
        {
            get { return _y; }
            set { _y = value; }
        }
        #endregion

        /*--------------------------------------------------------------------------------
         * Operator Overloads
         *------------------------------------------------------------------------------*/
        #region Operator Overloads
        /// <summary>
        /// Addition operator overload.
        /// </summary>
        /// <param name="left">Left-side item.</param>
        /// <param name="right">Right side item.</param>
        /// <returns>
        /// A new <see cref="PointReference"/> instance containing the sum.
        /// </returns>
        public static PointReference operator +(PointReference left, PointReference right)
        {
            return new PointReference(left.X + right.X, left.Y + right.Y);
        }
        /// <summary>
        /// Addition operator overload.
        /// </summary>
        /// <param name="left">Left-side item.</param>
        /// <param name="right">Right side item.</param>
        /// <returns>
        /// A new <see cref="PointReference"/> instance containing the sum.
        /// </returns>
        public static PointReference operator +(PointReference left, Point right)
        {
            return new PointReference(left.X + right.X, left.Y + right.Y);
        }
        /// <summary>
        /// Subtraction operator overload.
        /// </summary>
        /// <param name="left">Left-side item.</param>
        /// <param name="right">Right side item.</param>
        /// <returns>
        /// A new <see cref="PointReference"/> instance containing the sum.
        /// </returns>
        public static PointReference operator -(PointReference left, PointReference right)
        {
            return new PointReference(left.X - right.X, left.Y - right.Y);
        }
        /// <summary>
        /// Subtraction operator overload.
        /// </summary>
        /// <param name="left">Left-side item.</param>
        /// <param name="right">Right side item.</param>
        /// <returns>
        /// A new <see cref="PointReference"/> instance containing the sum.
        /// </returns>
        public static PointReference operator -(PointReference left, Point right)
        {
            return new PointReference(left.X - right.X, left.Y - right.Y);
        }
        /// <summary>
        /// Multiplication operator overload.
        /// </summary>
        /// <param name="left">Left-side item.</param>
        /// <param name="right">Right side item.</param>
        /// <returns>
        /// A new <see cref="PointReference"/> instance containing the result.
        /// </returns>
        public static PointReference operator *(PointReference left, PointReference right)
        {
            return new PointReference(left.X * right.X, left.Y * right.Y);
        }
        /// <summary>
        /// Multiplication operator overload.
        /// </summary>
        /// <param name="left">Left-side item.</param>
        /// <param name="right">Right side item.</param>
        /// <returns>
        /// A new <see cref="PointReference"/> instance containing the result.
        /// </returns>
        public static PointReference operator *(PointReference left, Point right)
        {
            return new PointReference(left.X * right.X, left.Y * right.Y);
        }
        /// <summary>
        /// Division operator overload.
        /// </summary>
        /// <param name="left">Left-side item.</param>
        /// <param name="right">Right side item.</param>
        /// <returns>
        /// A new <see cref="PointReference"/> instance containing the sum.
        /// </returns>
        public static PointReference operator /(PointReference left, PointReference right)
        {
            return new PointReference(left.X / right.X, left.Y / right.Y);
        }
        /// <summary>
        /// Division operator overload.
        /// </summary>
        /// <param name="left">Left-side item.</param>
        /// <param name="right">Right side item.</param>
        /// <returns>
        /// A new <see cref="PointReference"/> instance containing the sum.
        /// </returns>
        public static PointReference operator /(PointReference left, Point right)
        {
            return new PointReference(left.X / right.X, left.Y / right.Y);
        }
        /// <summary>
        /// Converts a <b>PointRefrence</b> instance to a System.Drawing.<b>Point</b> structure.
        /// </summary>
        /// <param name="original">
        /// The <see cref="PointReference"/> instance to be converted.
        /// </param>
        /// <returns>
        /// A new <see cref="System.Drawing.Point"/> structure.
        /// </returns>
        public static explicit operator Point(PointReference original)
        {
            return original.ToPoint();
        }
        /// <summary>
        /// Converts a <b>Point</b> structure to a <b>PointReference</b> reference.
        /// </summary>
        /// <param name="original">
        /// The <see cref="Point"/> structure to be converted.
        /// </param>
        /// <returns>
        /// A new <see cref="PointReference"/> instance.
        /// </returns>
        public static explicit operator PointReference(Point original)
        {
            return new PointReference(original.X, original.Y);
        }
        #endregion

        /*--------------------------------------------------------------------------------
         * Public Methods / Functions
         *------------------------------------------------------------------------------*/
        #region Public Methods / Functions
        /// <summary>
        /// Clears the contents of the object instance without disposing of the instance.
        /// </summary>
        public void Clear()
        {
            _x = 0;
            _y = 0;
        }
        /// <summary>
        /// Determineds whether two instances are equal.
        /// </summary>
        /// <param name="obj">
        /// An item to compare against.
        /// </param>
        /// <returns>
        /// <b>true</b> if the two references have the same values; otherwise, <b>false</b>.
        /// </returns>
        public override bool Equals(object obj)
        {
            if (obj is Point)
                return Equals(obj);
            else if (obj is PointReference)
                return Equals(obj);
            else
                return false;
        }
        /// <summary>
        /// Determines wheterh the supplied reference values equal the current
        /// instance's values.
        /// </summary>
        /// <param name="reference">
        /// The instance to compare against.
        /// </param>
        /// <returns>
        /// <b>true</b> if the two references have the same values; otherwise, <b>false</b>.
        /// </returns>
        public bool Equals(PointReference reference)
        {
            return ((reference.X == _x) && (reference.Y == _y));
        }
        /// <summary>
        /// Determines wheterh the supplied reference values equal the current
        /// instance's values.
        /// </summary>
        /// <param name="valueType">
        /// The <b>Point</b> to compare against.
        /// </param>
        /// <returns>
        /// <b>true</b> if the two references have the same values; otherwise, <b>false</b>.
        /// </returns>
        public bool Equals(Point valueType)
        {
            return ((valueType.X == _x) && (valueType.Y == _y));
        }
        /// <summary>
        /// Gets a hash code value for the current object instance.
        /// </summary>
        /// <returns>
        /// An integer hash code value.
        /// </returns>
        public override int GetHashCode()
        {
            return _x.GetHashCode() + _y.GetHashCode();
        }
        /// <summary>
        /// Parses the string content into a new object instance.
        /// </summary>
        /// <param name="content">
        /// The string content to be parsed.
        /// </param>
        /// <returns>
        /// A <see cref="PointReference"/> instance.
        /// </returns>
        public static PointReference Parse(string content)
        {
            PointReference returnValue = null;      //Return value.
            int left = 0;                           //Left or X value.
            int top = 0;                            //Top or Y value.
            int charIndex = -1;                     //Character index location.

            returnValue = new PointReference();
            if ((content != null) && (content.Length > 0))
            {
                charIndex = content.IndexOf(",");
                if (charIndex == 0)
                {
                    try
                    {
                        left = Convert.ToInt32(content);
                    }
                    catch
                    {
                    }
                }
                else
                {
                    try
                    {
                        left = Convert.ToInt32(content.Substring(0, charIndex));
                        top = Convert.ToInt32(content.Substring(charIndex+1, content.Length - (charIndex+1)));
                    }
                    catch
                    {
                    }
                }

                returnValue.X = left;
                returnValue.Y = top;
            }

            return returnValue;
        }
        /// <summary>
        /// Returns a string representation of the current instance.
        /// </summary>
        /// <returns>
        /// A string representation of the current instance in the format: x,y.
        /// </returns>
        public override string ToString()
        {
            return _x.ToString() + "," + _y.ToString();
        }
        /// <summary>
        /// Translates the current instance to a <b>Point</b> structure.
        /// </summary>
        /// <returns>
        /// A <see cref="System.Drawing.Point"/> structure with the same
        /// values.
        /// </returns>
        public Point ToPoint()
        {
            return new Point(_x, _y);
        }
        #endregion
    }
}
